<?php

namespace App\Http\Controllers\Blade\DataExcel;

use App\Http\Controllers\Controller;
use App\Imports\DataExcelImport;
use App\Models\Category;
use App\Models\SubCategory;
use App\Models\DataExcel;
use App\Models\Sender;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Requests\UploadDataExcel;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\StreamedResponse;

class DataExcelController extends Controller
{
    public function uploadFile()
    {
        $categories = Category::all();
        $subcategories = SubCategory::all();

        return view('dashboard.excel.add',compact('categories','subcategories'));
    }
 
    public function downloadFileExcel(UploadDataExcel $request)
    {
        if (!$request->hasFile('file')) {
            toastr()->error('Please upload at least one file.');
            return redirect()->back();
        }
        $files = $request->file('file');
        $invalidData = [];
    
        if (empty($request->category_name) || empty($request->subcategory_name)) {
            toastr()->error('Category and Subcategory are required.');
            return redirect()->back();
        }
    
        $category = Category::findOrFail($request->category_name);
        $cat = Category::updateOrCreate(['name' => $category->name]);
    
        $subcategory = Subcategory::findOrFail($request->subcategory_name[0]);
        $subcat = Subcategory::updateOrCreate([
            'name' => $subcategory->name,
            'category_id' => $cat->id
        ]);
    
        $emailsSeen = [];
    
        try {
            foreach ($files as $file) {
                $fileName = time() . '-' . uniqid() . '.' . $file->getClientOriginalExtension();
                $destinationPath = storage_path('uploads/excel_files/');
                if (!file_exists($destinationPath)) {
                    mkdir($destinationPath, 0777, true);
                }
    
                $file->move($destinationPath, $fileName);
                $filePath = $destinationPath . $fileName;
    
                $rows = Excel::toArray(null, $filePath)[0];
    
                if (empty($rows) || count($rows) < 2) {
                    toastr()->error('The uploaded Excel file is empty or has no data.');
                    return redirect()->back();
                }
    
                $originalHeaders = array_map(fn($header) => strtolower(trim(preg_replace('/\s+/', '', $header))), $rows[0]);
    
                $headerMap = [
                    'destination_name' => ['اسم الجهة','أسم الجهة','اسم الشركة','أسم المؤسسة','company','company name','corporation','corporation name','اسم العميل','client name','destination_name'],
                    'address' => ['address','location','العنوان','عنوان'],
                    'phone' => ['phone','telephone','mobile','تليفون','موبايل','هاتف','جوال'],
                    'phone2' => ['phone2','telephone2','mobile2','تليفون2','موبايل2','هاتف2','جوال2'],
                    'email' => ['email','email address','الايميل'],
                    'country' => ['country','بلد'],
                    'website' => ['website'],
                    'google_map' => ['google map','map','googlemap','google_map'],
                    'responsible_name' => ['name','full name','اسم المسؤول','الموظف','صاحب الشركة','first name','last name'],
                ];
                $normalizedHeaders = [];
                foreach ($headerMap as $key => $aliases) {
                    foreach ($aliases as $alias) {
                        $cleaned = strtolower(trim(preg_replace('/\s+/', '', $alias)));
                        if (($index = array_search($cleaned, $originalHeaders)) !== false) {
                            $normalizedHeaders[$key][] = $index;
                        }
                    }
                }
    
                for ($i = 1; $i < count($rows); $i++) {
                    $row = array_map(fn($v) => trim(preg_replace('/\s+/', '', $v)), $rows[$i]);
                    $rowAssoc = [];
    
                    foreach ($normalizedHeaders as $field => $indexes) {
                        $values = array_map(fn($i) => $row[$i] ?? null, $indexes);
                        if ($field === 'responsible_name') {
                            $rowAssoc[$field] = trim(implode(' ', array_filter($values)));
                        } else {
                            $rowAssoc[$field] = $values[0] ?? null;
                        }
                    }
    
                    if (!array_filter($rowAssoc)) continue;
                    $rowAssoc['phone'] = preg_replace('/\s+/', '', $rowAssoc['phone'] ?? '');
                    $rowAssoc['phone2'] = preg_replace('/\s+/', '', $rowAssoc['phone2'] ?? '');

                    $isValidPhone = fn($num) => preg_match('/^\+?\d+$/', $num);

                    $cleanPhone = $isValidPhone($rowAssoc['phone']) ? $rowAssoc['phone'] : null;
                    $cleanPhone2 = $isValidPhone($rowAssoc['phone2']) ? $rowAssoc['phone2'] : null;
                    if ($cleanPhone === null && $cleanPhone2 === null) {
                        $rejectionReason[] = 'Invalid phones';
                        $rowAssoc['rejection_reason'] = implode(', ', $rejectionReason);
                        $invalidData[] = $rowAssoc;
                        continue;
                    }

                    if ($cleanPhone === null && $cleanPhone2) {
                        $rowAssoc['phone'] = null;
                    }
                    if ($cleanPhone2 === null && $cleanPhone) {
                        $rowAssoc['phone2'] = null;
                    }

                    $email = strtolower(trim($rowAssoc['email'] ?? ''));
                    $rejectionReason = [];
    
                    if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                        $rejectionReason[] = 'Invalid email';
                    }
    
                    if (in_array($email, $emailsSeen)) {
                        $rejectionReason[] = 'Duplicate email';
                    }
    
                    if (!$rowAssoc['destination_name'] || !$rowAssoc['country']) {
                        $rejectionReason[] = 'Missing destination_name or country';
                    }
    
                    if (!$rowAssoc['address']) {
                        $rejectionReason[] = 'Missing address';
                    }
    
                    if (!empty($rejectionReason)) {
                        $rowAssoc['rejection_reason'] = implode(', ', $rejectionReason);
                        $invalidData[] = $rowAssoc;
                        continue;
                    }
    
                    $emailsSeen[] = $email;
                    $exists = DataExcel::where('email', $email)
                        ->where('destination_name', $rowAssoc['destination_name'])
                        ->where('address', $rowAssoc['address'])
                        ->where('phone', $cleanPhone)
                        ->where('phone2', $cleanPhone2)
                        ->exists();
    
                    if ($exists) {
                        toastr()->error('This data already exists!');
                        return redirect()->back();
                    }
                    $dataExcel = DataExcel::updateOrCreate([
                        'destination_name' => $rowAssoc['destination_name'],
                        'address' => $rowAssoc['address'],
                        'phone' => $cleanPhone,
                        'phone2' => $cleanPhone2,
                        'email' => $email,
                        'country' => $rowAssoc['country'],
                        'website' => $rowAssoc['website'] ?? null,
                        'google_map' => $rowAssoc['google_map'] ?? null,
                        'responsible_name' => $rowAssoc['responsible_name'] ?? null,
                        'category_id' => $cat->id,
                        'subcategory_id' => $subcat->id,
                    ]);
    
                    $dataExcel->messages()->attach($request->message_id);
                }
            }
    
            if (!empty($invalidData)) {
                session()->put('invalidData', $invalidData);
                toastr()->warning('Import done with some invalid data. You can download the invalid data file.');
                return redirect()->route('home.index')->with('showDownloadButton', true);
            }
    
            toastr()->success('All files have been imported successfully.');
            return redirect()->route('home.index');
    
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => 'Error importing data: ' . $e->getMessage(),
            ], 500);
        }
    }

   public function downloadInvalidDataReport()
 { 
    $invalidData = session()->get('invalidData', []);
    
    if (empty($invalidData)) {
        toastr()->error('No invalid data to download.');
        return redirect()->route('home.index');
    }
    $headers = [
        'destination_name' => 'Destination Name',
        'address' => 'Address',
        'phone' => 'Phone',
        'phone2' => 'Phone 2',
        'email' => 'Email',
        'country' => 'Country',
        'website' => 'Website',
        'google_map' => 'Google Map',
        'responsible_name' => 'Responsible Name',
        'rejection_reason' => 'Rejection Reason'
    ];
    $response = new StreamedResponse(function () use ($invalidData, $headers) {
        $output = fopen('php://output', 'w');
        fputcsv($output, array_values($headers));
        foreach ($invalidData as $row) {
            $data = [
                $row['destination_name'] ?? '',
                $row['address'] ?? '',
                $row['phone'] ?? '',
                $row['phone2'] ?? '',
                $row['email'] ?? '',
                $row['country'] ?? '',
                $row['website'] ?? '',
                $row['google_map'] ?? '',
                $row['responsible_name'] ?? '',
                $row['rejection_reason'] ?? ''
            ];
            fputcsv($output, $data);
        }

        fclose($output);
    });
    $response->headers->set('Content-Type', 'text/csv');
    $response->headers->set('Content-Disposition', 'attachment; filename="invalid_data_report.csv"');

    return $response;
 }

  
}